package com.hytc.mymall.view;

import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;

import java.util.LinkedList;
import java.util.Queue;

/**
 * Created by Administrator on 2016/12/2.
 */

public class HorizontalListView extends AdapterView<ListAdapter>
{
    protected ListAdapter mAdapter;
    public boolean mAlwaysOverrideTouch;
    protected int mCurrentX;
    private boolean mDataChanged;
    private DataSetObserver mDataObserver;
    private int mDisplayOffset;
    private GestureDetector mGesture;
    private int mLeftViewIndex;
    private int mMaxX;
    protected int mNextX;
    private GestureDetector.OnGestureListener mOnGesture;
    private OnItemClickListener mOnItemClicked;
    private OnItemLongClickListener mOnItemLongClicked;
    private OnItemSelectedListener mOnItemSelected;
    private Queue<View> mRemovedViewQueue;
    private int mRightViewIndex;
    protected Scroller mScroller;

    public HorizontalListView(final Context context, final AttributeSet set) {
        super(context, set);
        this.mAlwaysOverrideTouch = true;
        this.mLeftViewIndex = -1;
        this.mRightViewIndex = 0;
        this.mMaxX = Integer.MAX_VALUE;
        this.mDisplayOffset = 0;
        this.mRemovedViewQueue = new LinkedList<View>();
        this.mDataChanged = false;
        this.mDataObserver = new DataSetObserver() {
            public void onChanged() {
                synchronized (HorizontalListView.this) {
                    HorizontalListView.access$2(HorizontalListView.this, true);
                    // monitorexit(this.this$0)
                    HorizontalListView.this.invalidate();
                    HorizontalListView.this.requestLayout();
                }
            }

            public void onInvalidated() {
                HorizontalListView.this.reset();
                HorizontalListView.this.invalidate();
                HorizontalListView.this.requestLayout();
            }
        };
        this.mOnGesture = (GestureDetector.OnGestureListener)new GestureDetector.SimpleOnGestureListener() {
            private boolean isEventWithinView(final MotionEvent motionEvent, final View view) {
                final Rect rect = new Rect();
                final int[] array = new int[2];
                view.getLocationOnScreen(array);
                final int n = array[0];
                final int n2 = n + view.getWidth();
                final int n3 = array[1];
                rect.set(n, n3, n2, n3 + view.getHeight());
                return rect.contains((int)motionEvent.getRawX(), (int)motionEvent.getRawY());
            }

            public boolean onDown(final MotionEvent motionEvent) {
                return HorizontalListView.this.onDown(motionEvent);
            }

            public boolean onFling(final MotionEvent motionEvent, final MotionEvent motionEvent2, final float n, final float n2) {
                return HorizontalListView.this.onFling(motionEvent, motionEvent2, n, n2);
            }

            public void onLongPress(final MotionEvent motionEvent) {
                final int childCount = HorizontalListView.this.getChildCount();
                int i = 0;
                while (i < childCount) {
                    final View child = HorizontalListView.this.getChildAt(i);
                    if (this.isEventWithinView(motionEvent, child)) {
                        if (HorizontalListView.this.mOnItemLongClicked != null) {
                            HorizontalListView.this.mOnItemLongClicked.onItemLongClick((AdapterView)HorizontalListView.this, child, i + (1 + HorizontalListView.this.mLeftViewIndex), HorizontalListView.this.mAdapter.getItemId(i + (1 + HorizontalListView.this.mLeftViewIndex)));
                            return;
                        }
                        break;
                    }
                    else {
                        ++i;
                    }
                }
            }

            public boolean onScroll(final MotionEvent motionEvent, final MotionEvent motionEvent2, final float n, final float n2) {
                synchronized (HorizontalListView.this) {
                    final HorizontalListView this$0 = HorizontalListView.this;
                    this$0.mNextX += (int)n;
                    // monitorexit(this.this$0)
                    HorizontalListView.this.requestLayout();
                    return true;
                }
            }

            public boolean onSingleTapConfirmed(final MotionEvent motionEvent) {
                int i = 0;
                while (i < HorizontalListView.this.getChildCount()) {
                    final View child = HorizontalListView.this.getChildAt(i);
                    if (this.isEventWithinView(motionEvent, child)) {
                        if (HorizontalListView.this.mOnItemClicked != null) {
                            HorizontalListView.this.mOnItemClicked.onItemClick((AdapterView)HorizontalListView.this, child, i + (1 + HorizontalListView.this.mLeftViewIndex), HorizontalListView.this.mAdapter.getItemId(i + (1 + HorizontalListView.this.mLeftViewIndex)));
                        }
                        if (HorizontalListView.this.mOnItemSelected != null) {
                            HorizontalListView.this.mOnItemSelected.onItemSelected((AdapterView)HorizontalListView.this, child, i + (1 + HorizontalListView.this.mLeftViewIndex), HorizontalListView.this.mAdapter.getItemId(i + (1 + HorizontalListView.this.mLeftViewIndex)));
                            break;
                        }
                        break;
                    }
                    else {
                        ++i;
                    }
                }
                return true;
            }
        };
        this.initView();
    }

    static /* synthetic */ void access$2(final HorizontalListView horizontalListView, final boolean mDataChanged) {
        horizontalListView.mDataChanged = mDataChanged;
    }

    private void addAndMeasureChild(final View view, final int n) {
        LayoutParams layoutParams = view.getLayoutParams();
        if (layoutParams == null) {
            layoutParams = new LayoutParams(-1, -1);
        }
        this.addViewInLayout(view, n, layoutParams, true);
        //MeasureSpec.AT_MOST不确定元素
        view.measure(MeasureSpec.makeMeasureSpec(this.getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(this.getHeight(),  MeasureSpec.AT_MOST));
    }

    private void fillList(final int n) {
        final View child = this.getChildAt(-1 + this.getChildCount());
        int right = 0;
        if (child != null) {
            right = child.getRight();
        }
        this.fillListRight(right, n);
        final View child2 = this.getChildAt(0);
        int left = 0;
        if (child2 != null) {
            left = child2.getLeft();
        }
        this.fillListLeft(left, n);
    }

    private void fillListLeft(int n, final int n2) {
        while (n + n2 > 0 && this.mLeftViewIndex >= 0) {
            final View view = this.mAdapter.getView(this.mLeftViewIndex, (View)this.mRemovedViewQueue.poll(), (ViewGroup)this);
            this.addAndMeasureChild(view, 0);
            n -= view.getMeasuredWidth();
            --this.mLeftViewIndex;
            this.mDisplayOffset -= view.getMeasuredWidth();
        }
    }

    private void fillListRight(int n, final int n2) {
        while (n + n2 < this.getWidth() && this.mRightViewIndex < this.mAdapter.getCount()) {
            final View view = this.mAdapter.getView(this.mRightViewIndex, (View)this.mRemovedViewQueue.poll(), (ViewGroup)this);
            this.addAndMeasureChild(view, -1);
            n += view.getMeasuredWidth();
            if (this.mRightViewIndex == -1 + this.mAdapter.getCount()) {
                this.mMaxX = n + this.mCurrentX - this.getWidth();
            }
            if (this.mMaxX < 0) {
                this.mMaxX = 0;
            }
            ++this.mRightViewIndex;
        }
    }

    private void initView() {
        synchronized (this) {
            this.mLeftViewIndex = -1;
            this.mRightViewIndex = 0;
            this.mDisplayOffset = 0;
            this.mCurrentX = 0;
            this.mNextX = 0;
            this.mMaxX = Integer.MAX_VALUE;
            this.mScroller = new Scroller(this.getContext());
            this.mGesture = new GestureDetector(this.getContext(), this.mOnGesture);
        }
    }

    private void positionItems(final int n) {
        if (this.getChildCount() > 0) {
            this.mDisplayOffset += n;
            int mDisplayOffset = this.mDisplayOffset;
            for (int i = 0; i < this.getChildCount(); ++i) {
                final View child = this.getChildAt(i);
                final int measuredWidth = child.getMeasuredWidth();
                child.layout(mDisplayOffset, 0, mDisplayOffset + measuredWidth, child.getMeasuredHeight());
                mDisplayOffset += measuredWidth + child.getPaddingRight();
            }
        }
    }

    private void removeNonVisibleItems(final int n) {
        for (View view = this.getChildAt(0); view != null && n + view.getRight() <= 0; view = this.getChildAt(0)) {
            this.mDisplayOffset += view.getMeasuredWidth();
            this.mRemovedViewQueue.offer(view);
            this.removeViewInLayout(view);
            ++this.mLeftViewIndex;
        }
        for (View view2 = this.getChildAt(-1 + this.getChildCount()); view2 != null && n + view2.getLeft() >= this.getWidth(); view2 = this.getChildAt(-1 + this.getChildCount())) {
            this.mRemovedViewQueue.offer(view2);
            this.removeViewInLayout(view2);
            --this.mRightViewIndex;
        }
    }

    private void reset() {
        synchronized (this) {
            this.initView();
            this.removeAllViewsInLayout();
            this.requestLayout();
        }
    }

    public boolean dispatchTouchEvent(final MotionEvent motionEvent) {
        return super.dispatchTouchEvent(motionEvent) | this.mGesture.onTouchEvent(motionEvent);
    }

    public ListAdapter getAdapter() {
        return this.mAdapter;
    }

    public View getSelectedView() {
        return null;
    }

    protected boolean onDown(final MotionEvent motionEvent) {
        this.mScroller.forceFinished(true);
        return true;
    }

    protected boolean onFling(final MotionEvent motionEvent, final MotionEvent motionEvent2, final float n, final float n2) {
        synchronized (this) {
            this.mScroller.fling(this.mNextX, 0, (int)(-n), 0, 0, this.mMaxX, 0, 0);
            // monitorexit(this)
            this.requestLayout();
            return true;
        }
    }

    protected void onLayout(final boolean b, final int n, final int n2, final int n3, final int n4) {
        synchronized (this) {
            super.onLayout(b, n, n2, n3, n4);
            if (this.mAdapter != null) {
                if (this.mDataChanged) {
                    final int mCurrentX = this.mCurrentX;
                    this.initView();
                    this.removeAllViewsInLayout();
                    this.mNextX = mCurrentX;
                    this.mDataChanged = false;
                }
                if (this.mScroller.computeScrollOffset()) {
                    this.mNextX = this.mScroller.getCurrX();
                }
                if (this.mNextX <= 0) {
                    this.mNextX = 0;
                    this.mScroller.forceFinished(true);
                }
                if (this.mNextX >= this.mMaxX) {
                    this.mNextX = this.mMaxX;
                    this.mScroller.forceFinished(true);
                }
                final int n5 = this.mCurrentX - this.mNextX;
                this.removeNonVisibleItems(n5);
                this.fillList(n5);
                this.positionItems(n5);
                this.mCurrentX = this.mNextX;
                if (!this.mScroller.isFinished()) {
                    this.post((Runnable)new Runnable() {
                        @Override
                        public void run() {
                            HorizontalListView.this.requestLayout();
                        }
                    });
                }
            }
        }
    }

    public void scrollTo(final int n) {
        synchronized (this) {
            this.mScroller.startScroll(this.mNextX, 0, n - this.mNextX, 0);
            this.requestLayout();
        }
    }

    public void setAdapter(final ListAdapter mAdapter) {
        if (this.mAdapter != null) {
            this.mAdapter.unregisterDataSetObserver(this.mDataObserver);
        }
        (this.mAdapter = mAdapter).registerDataSetObserver(this.mDataObserver);
        this.reset();
    }

    public void setOnItemClickListener(final OnItemClickListener mOnItemClicked) {
        this.mOnItemClicked = mOnItemClicked;
    }

    public void setOnItemLongClickListener(final OnItemLongClickListener mOnItemLongClicked) {
        this.mOnItemLongClicked = mOnItemLongClicked;
    }

    public void setOnItemSelectedListener(final OnItemSelectedListener mOnItemSelected) {
        this.mOnItemSelected = mOnItemSelected;
    }

    public void setSelection(final int n) {
    }
}
